FWU: Introduce FWU_SMC_IMAGE_RESET
authorAntonio Nino Diaz <antonio.ninodiaz@arm.com>
Fri, 12 May 2017 15:51:59 +0000 (16:51 +0100)
committerAntonio Nino Diaz <antonio.ninodiaz@arm.com>
Thu, 1 Jun 2017 13:52:12 +0000 (14:52 +0100)
This SMC is as a means for the image loading state machine to go from
COPYING, COPIED or AUTHENTICATED states to RESET state. Previously, this
was only done when the authentication of an image failed or when the
execution of the image finished.

Documentation updated.

Change-Id: Ida6d4c65017f83ae5e27465ec36f54499c6534d9
Signed-off-by: Antonio Nino Diaz <antonio.ninodiaz@arm.com>
bl1/bl1_fwu.c
docs/firmware-update.md
include/bl1/bl1.h

index 43bb4d2baed47758466d0a1168405c6059f956b3..205ea92238afc45b68a9a3870990d9a6b6ef4616 100644 (file)
@@ -40,6 +40,8 @@ static register_t bl1_fwu_image_resume(register_t image_param,
                        unsigned int flags);
 static int bl1_fwu_sec_image_done(void **handle,
                        unsigned int flags);
+static int bl1_fwu_image_reset(unsigned int image_id,
+                       unsigned int flags);
 __dead2 static void bl1_fwu_done(void *client_cookie, void *reserved);
 
 /*
@@ -47,6 +49,9 @@ __dead2 static void bl1_fwu_done(void *client_cookie, void *reserved);
  */
 static unsigned int sec_exec_image_id = INVALID_IMAGE_ID;
 
+/* Authentication status of each image. */
+extern unsigned int auth_img_flags[];
+
 void cm_set_next_context(void *cpu_context);
 
 /*******************************************************************************
@@ -78,6 +83,9 @@ register_t bl1_fwu_smc_handler(unsigned int smc_fid,
        case FWU_SMC_SEC_IMAGE_DONE:
                SMC_RET1(handle, bl1_fwu_sec_image_done(&handle, flags));
 
+       case FWU_SMC_IMAGE_RESET:
+               SMC_RET1(handle, bl1_fwu_image_reset(x1, flags));
+
        case FWU_SMC_UPDATE_DONE:
                bl1_fwu_done((void *)x1, NULL);
                /* We should never return from bl1_fwu_done() */
@@ -666,3 +674,56 @@ __dead2 static void bl1_fwu_done(void *client_cookie, void *reserved)
        bl1_plat_fwu_done(client_cookie, reserved);
        assert(0);
 }
+
+/*******************************************************************************
+ * This function resets an image to IMAGE_STATE_RESET. It fails if the image is
+ * being executed.
+ ******************************************************************************/
+static int bl1_fwu_image_reset(unsigned int image_id, unsigned int flags)
+{
+       image_desc_t *image_desc = bl1_plat_get_image_desc(image_id);
+
+       if ((!image_desc) || (GET_SECURITY_STATE(flags) == SECURE)) {
+               WARN("BL1-FWU: Reset not allowed due to invalid args\n");
+               return -EPERM;
+       }
+
+       switch (image_desc->state) {
+
+       case IMAGE_STATE_RESET:
+               /* Nothing to do. */
+               break;
+
+       case IMAGE_STATE_INTERRUPTED:
+       case IMAGE_STATE_AUTHENTICATED:
+       case IMAGE_STATE_COPIED:
+       case IMAGE_STATE_COPYING:
+
+               if (bl1_fwu_remove_loaded_id(image_id)) {
+                       WARN("BL1-FWU: Image reset couldn't find the image ID\n");
+                       return -EPERM;
+               }
+
+               /* Clear the memory.*/
+               zero_normalmem((void *)image_desc->image_info.image_base,
+                               image_desc->copied_size);
+               flush_dcache_range(image_desc->image_info.image_base,
+                               image_desc->copied_size);
+
+               /* Reset status variables */
+               image_desc->copied_size = 0;
+               image_desc->image_info.image_size = 0;
+               image_desc->state = IMAGE_STATE_RESET;
+
+               /* Clear authentication state */
+               auth_img_flags[image_id] = 0;
+
+               break;
+
+       case IMAGE_STATE_EXECUTED:
+       default:
+               assert(0);
+       }
+
+       return 0;
+}
index 56ef15cbb2f487452535b0a8565c594ae1eb1884..e3eec26f98ba06193655da7ae945df4b5d306c91 100644 (file)
@@ -117,6 +117,7 @@ The following is a brief description of the supported states:
 *   RESET:         This is the initial state of every image at the start of FWU.
                    Authentication failure also leads to this state. A secure
                    image may yield to this state if it has completed execution.
+                   It can also be reached by using `FWU_SMC_IMAGE_RESET`.
 
 *   COPYING:       This is the state of a secure image while BL1 is copying it
                    in blocks from non-secure to secure memory.
@@ -356,9 +357,28 @@ function `bl1_plat_fwu_done`, passing the optional argument `client_cookie` as
 a `void *`. The SMC does not return.
 
 
+### FWU_SMC_IMAGE_RESET
+
+    Arguments:
+        uint32_t     function ID : 0x16
+        unsigned int image_id
+
+    Return:
+        int : 0 (Success)
+            : -EPERM
+
+    Pre-conditions:
+        if (secure world caller) return -EPERM
+        if (image in EXECUTED) return -EPERM
+
+This SMC sets the state of an image to RESET and zeroes the memory used by it.
+
+This is only allowed if the image is not being executed.
+
+
 - - - - - - - - - - - - - - - - - - - - - - - - - -
 
-_Copyright (c) 2015-2016, ARM Limited and Contributors. All rights reserved._
+_Copyright (c) 2015-2017, ARM Limited and Contributors. All rights reserved._
 
 
 [Porting Guide]:        ./porting-guide.md
index 8f4f992cd6d5f624e338a1bc95dacfbea94a13ad..1544523517e967797f37d2785ac05bcf10efb3e8 100644 (file)
 #define FWU_SMC_IMAGE_RESUME           0x13
 #define FWU_SMC_SEC_IMAGE_DONE         0x14
 #define FWU_SMC_UPDATE_DONE            0x15
+#define FWU_SMC_IMAGE_RESET            0x16
 
 /*
  * Number of FWU calls (above) implemented
  */
-#define FWU_NUM_SMC_CALLS              6
+#define FWU_NUM_SMC_CALLS              7
 
 #if TRUSTED_BOARD_BOOT
 # define BL1_NUM_SMC_CALLS             (FWU_NUM_SMC_CALLS + 4)
@@ -56,7 +57,7 @@
  * calls from the SMC function ID
  */
 #define FWU_SMC_FID_START              FWU_SMC_IMAGE_COPY
-#define FWU_SMC_FID_END                        FWU_SMC_UPDATE_DONE
+#define FWU_SMC_FID_END                        FWU_SMC_IMAGE_RESET
 #define is_fwu_fid(_fid) \
     ((_fid >= FWU_SMC_FID_START) && (_fid <= FWU_SMC_FID_END))